------------------------------- Hareng-tool -------------------------------

Version 1.2 beta
28/11/2006

 --------------
| Introduction |
 --------------

Ce programme a pour but de fournir des outils utiles pour le romhacking, il
contient actuellement :
   - un extracteur
   - un insreur
   - un extracteur pour des mots de longueur fixe
   - un insreur pour des mots de longueur fixe
   - un optimisateur de DTE
   - un optimisateur de MTE
   - un module permettant de remettre en forme automatiquement les textes
   - un module qui permet de supprimer des mots d'un fichier  partir d'une
     liste de mots
   - un patcheur/crateur de patch IPS

Le tout est bas sur un interprteur Lua.
Le descriptif de l'API Lua se trouve dans le fichier "readme_lua.txt".


 ---------------------------------------------------
| Modifications par rapport  la version prcdente |
 ---------------------------------------------------

- Par rapport  la version prcdante, les ajouts sont :
     - un patcheur/crateur de patch IPS
     - l'extracteur/insreur a t amlior du niveau des possibilits avec Lua.

- Correction d'un bug de mmoire dans l'insreur et l'insreur fixe.
- L'optimisateur MTE est un peu plus prcis dans les options demandes.
- Un Makefile a enfin t rajout.
- Le programme a t test sous Mac OS X, il y avait une petite erreur de compilation
  qui est mainenant corrige. Le test a t ralis sur les processeurs PowerPC et Intel.
- Intgration de l'interprteur Lua 5.1.1 (version 5.0 dans les versions prcdentes).

 ------------
| Historique |
 ------------

Version 1.0 (25/12/2004) :
Premire version comportant:
   - un extracteur
   - un insreur
   - un extracteur pour des mots de longueur fixe
   - un insreur pour des mots de longueur fixe
   - un optimisateur de DTE
   - un optimisateur de MTE


Version 1.1 (20/09/2005) :
Par rapport  la version prcdente, les ajouts sont :
   - un module permettant de remettre en forme automatiquement les textes
   - un module qui permet de supprimer des mots d'un fichier  partir d'une
     liste de mots

De plus, le programme est maintenant scriptable en Lua (www.lua.org) et quelques
fonctions annexes ont t rajoutes.


 --------------------------------
| 1 - Utilisation de Hareng-tool |
 --------------------------------

Le programme est en mode console (il existe aussi une interface).
Pour l'excuter, il faut lui donner par la biais de
la ligne de commande un fichier texte contenant les instructions qu'il doit
executer. La ligne de commande doit avoir la syntaxe suivante :

	hareng-tool [option]

Il y a 3 options actuellement :
   -h : affiche un message d'aide
   -i : mode interactif
   -e [lua_script] : execute le fichier [lua_script]

Le mode interactif est un mode o il suffit de donner des instructions en Lua
directement par la console. Il est important de noter que l'interprteur fonctionne
par "blocs". En gros, si on veut lui faire faire une boucle for, il faut lui donner
en ENTIER. Pour ce faire, on peut crire la boucle en plusieurs lignes et  la fin de
chaque ligne intermdiaire, mettre un '\'. Exemple :

sor@Terra:~/Dev/hareng-tool$ hareng-tool.exe -i
Hareng-tool version 1.2 beta (c) 2004-2006 S.O.R
> for i = 0, 3 do
[string "in"]:1: `end' expected near `<eof>'
> for i = 0, 3 do\
>> print("YEAH !") \
>> end
YEAH !
YEAH !
YEAH !
>

Dans le premier cas on lui donne une ligne unique, il renvoie un message d'erreur.
Par contre dans le second cas on utilise le '\' pour lui spcifier qu'on n'a pas
fini de lui donner du code.

L'option -e permet l'execution du fichier de script Lua prcis.

La suite va expliquer comment utiliser de faon basique le programme, pour les informations
sur les possibilits de programmation en Lua, il faut voir du ct du fichier readme_lua.txt

 ----------------------------
| 2 - Les fichiers de script |
 ----------------------------

Le fichier de script doit tre crit en Lua. Pour ceux qui ne connaissent
pas ce langage et qui souhaitent l'apprendre, ils peuvent se rendre sur le
site officiel : www.lua.org.
Pour ceux qui ne veulent pas apprendre, le paragraphe suivant leur donnera
quelques explications basiques pour pouvoir utiliser le programme.

2.1 - Explication du fichier de script
---------------------------------------

Le fichier de script comporte des fonctions. Leur syntaxe est la
suivante :

   nom_fonction(argument1, argument2, ...)

"nom_fonction" est videment le nom de la fonction  executer. Il est suivi
d'une liste d'arguments de taille variable d'une mme fonction, parfois
mme pour une mme fonction. Les arguments sont imprativements spars par
des virgules, les espaces sparant un argument d'une virgule est purement
hsttique, ils n'entrent pas en compte dans l'argument lui mme. Cependant,
un argument ne peut pas contenir d'espace,  moins de l'crire entre guillemets.

Exemple :
   fonction(argument1,argument2)
est identique  :
   fonction(      argument1     ,    argument2     )

On peut crire :
   fonction("ceci est l'arguement 1")
Les guillemets permettent de donner des arguments qui sont des chaines de
caractre (comme des noms de fichier par exemple).

La liste d'arguments doit tre encadre par des parenthses comme l'exemple
le montre. Au final, un fichier de script est constitu de diffrentes
fonctions, par exemple pour des mots de longueur fixe :

   fonction1(argument1,argument2)
   fonction2(argument1,argument2)

Toute fonction est imprativement suivie d'un retour  la ligne.

Notez bien qu'on peut mettre une ligne en commentaire en plaant
'--' au dbut de cette ligne. Pour ceux qui ne savent pas ce qu'est un commentaire
en programmation, il s'agit d'une zone de texte qui n'est pas du code et qui
est tout simplement ignore.


2.2 - Liste des diffrentes fonctions disponibles
-------------------------------------------------

La liste des fonctions disponnible est la suivant :
   - extraire
   - inserer
   - extraire_fixe
   - inserer_fixe
   - optimiser_dte
   - optimiser_mte
   - supprimer_mots
   - mettre_en_forme
   - patcher
   - creer_pach

 -------------------------------------------
| 3 - Description de la fonction "extraire" |
 -------------------------------------------

Comme son nom l'indique, la fonction extraire permet d'extraire des textes.
Elle permet de grer les pointeurs. La table peut contenir des entres
codes sur plus de 10 octets (exactement jusqu' 255 mais je doute que
cel soit trs utile), et la chaine peut avoir une longueur aussi longue
que vous le souhaitez (sauf si vous mettez 1 go de texte derrire, a
fonctionnera pas trop :D).

Pour extraire un texte, il faut donner diverses informations :
   - le nom de la rom qui contient le texte  extraire
   - le nom de la table  utiliser
   - le nom du fichier texte o sera crit le texte extrait
   - l'adresse du dbut du texte
   - l'adresse de la fin du texte
   - l'adresse du dbut des pointeurs
   - le nombre de pointeurs
   - la manire de calculer les pointeurs

Les noms des divers fichiers peuvent dpasser les 8 caractres, en fait,
vous pouvez donner un nom de fichier aussi long que ceux que windows accepte.

Les diffrentes adresses peuvent tre donnes en hexadcimal (valeur
commenant par 0x), ou en dcimal.

Dans le fichier de sortie, les pointeurs apparaissent sous la forme :
<PTXXXX> o XXXX correspond  un nombre. Il ne faut en AUCUN CAS les
modifier.

Les tables utilisent le format suivant :
   valeur=chaine

Exemple :
   50=a
   408F=pe

D'une faon gnrale, le programme fait intervenir une notion de balise.
Une balise est en fait une entre de la table un peu spciale pour le
programme puisqu'elle est crite de la faon suivante :
   02=<FIN>

Les balises commencent toujours par '<' et finissent toujours par '>'.
Quand les utiliser me demandez-vous ?
Il faut les utiliser pour les octets "spciaux" comme les octets qui indiquent
un nouveau cadre, une fin de cadre, etc.
Ainsi vos dumps pourraient ressembler  ceci :
   There something written on the side...<NEW>Goemon was here!<FIN>

Ceci n'est pas spcialement esthtique, c'est pourquoi il serait utile d'avoir
en sortie :
   There something written on the side...
   <NEW>
   Goemon was here!
   <FIN>

Pour se faire, les entres seraient par exemple :
   01=\n<NEW>\n
   02=\n<FIN>\n\n

"\n" sera remplac dans le fichier de sortie par un retour  la ligne. Les balises
supportent donc ces informations (mais pas une entre "normale").



3.1 - Mode basique
------------------

La syntaxe du mode d'extraction "de base" est la suivante :
   extraire(nom_rom, nom_table, nom_texte, debut_texte, fin_texte, debut_pointeurs,
            nombre_pointeurs, taille_pointeurs, calcul_des_pointeurs, inversion)

Les noms des premiers arguments sont parlants, mais je vais dtailler  partir
de "taille_pointeurs". L'extracteur grant les pointeurs, il faut lui donner
des informations sur la manire de les calculer. En effet, l'extracteur a
besoin d'effectuer un calcul pour convertir les pointeurs en adresse PC.
La taille des pointeurs est exprime en octet afin de permettre au programme
de les charger correctement.
Ensuite il faut indiquer le calcul que le programme doit effectuer.
Un exemple de calcul :
   "X+$200"

X correspond au pointeur charg dans la rom, on peut alors lui faire subir
un calcul plus ou moins complexe (sont grs les oprateurs +, -, *, /,
% (reste de la division euclidienne) ainsi que les parenthses).
Par contre, pour l'instant, une valeur hexadcimale ne peut qu'tre indiqu par
un $ au dbut le la valeur.

Le dernier argument indique si l'on doit effectuer une inversion des octets
dans le pointeur charg. Deux choix sont possibles :
   - little_endian : ceci inversera les octets
   - big_endian : ceci n'inversera pas les octets

Supposons que l'on ait notre pointeur calcul et qu'il soit : 40 20 (en hexadcimal),
si vous indiquez little_endian, au final sa valeur sera 20 40, si vous indiquez
big_endian, sa valeur ne changera pas.

Pour finir, voici un exemple d'appel de fonction :
   extraire("Marom.smc", "Matable.tbl", "out.txt", 0x100, 0x500, 0x0, 50, 2, "X+$200", little_endian)

Ceci peut paraitre bien compliqu, mais il existe quelques modes prdfinis pour
simplifier la tache (leurs descriptions sont situes ci-dessous).


3.2 - Mode "16 bits"
--------------------

Le dernier exemple aurait pu tre crit de la faon suivante :
   extraire("Marom.smc", "Matable.tbl", "out.txt", 0x100, 0x500, "SNES16", 0x0, 50, 0x200, 0)

"SNES16" indique que les pointeurs sont des pointeurs 16 bits et que leurs ocets
doivent tre inverss. Ce mode peut tre utilis aussi pour tout pointeurs de ce
type, mme si la console n'est pas une SuperNes.

L'argument suivant "SNES16" correspond au dbut de la table de pointeurs,
le suivant au nombre de pointeurs.
Les deux derniers arguments indiquent une correction supplmentaire "simple" :
l'avant dernier correspond  une valeur  ajouter, le dernier  une valeur 
retrancher. Ainsi il est possible de simplifier vos fonctions en utilisant les
modes prdfinis qui permettent d'viter certaines erreurs.


3.3 - Mode "24 bits SuperNes HighRom"
-------------------------------------

L'utilisation de ce mode est identique au mode 16 bits. Pour l'utiliser il faut
juste crire "SNES24-HighRom" a lieu de "SNES16". Ce mode permet de calculer des
pointeurs 24 bits de rom SuperNes de type HighRom (le calcul additionnel reste
disponnible et est  utiliser dans la pluspart des cas).


3.4 - Mode "24 bits SuperNes LowRom"
------------------------------------

En fait, il n'y a pas un mode de ce type, mais deux. Sur SuperNes il existe deux
types de LowRom et la manire de calculer les pointeurs sur chacun d'eux diffre.

Pour utiliser le mode pour les LowRom1, il faut indiquer "SNES24-LowRom1".
Pour utiliser le mode pour les LowRom2, il faut indiquer "SNES24-LowRom2".

Je pense que ce mode sera peu utilis, mais vu la complexit sur calcul, j'ai
pris soin de le mettre.


3.5 - Mode "Sans pointeurs"
---------------------------

Il peut parfois arriver qu'on veuille extraire et insrer un texte sans pointeurs
ou sans vouloir se soucier des pointeurs. Au lieu d'viter d'crire une ligne
d'instructions un peu longue avec des informations inutiles, un mode d'extraction
et d'insertion sans pointeurs a t implment.
Il suffit juste de changer le "SNES16" par "SANS_POINTEURS" et de ne donner aucun
argument supplmentaire.

Exemple :

   extraire("Marom.smc", "Matable.tbl", "out.txt", 0x100, 0x500, "SANS_POINTEURS")



 ------------------------------------------
| 3 - Description de la fonction "inserer" |
 ------------------------------------------

Cette fonction permet d'insrer les scripts crs par la fonction "extraire".
Son utilisation est identique au niveau de la syntaxe et des modes disponibles.


 ------------------------------------------------
| 4 - Description de la fonction "extraire_fixe" |
 ------------------------------------------------

Il arrive parfois que pour des objets dans un jeu, le texte soit prsent de
manire "spciale". Par exemple, les objets d'un jeu peuvent ne pas avoir de
pointeur et tre cod sur un nombre d'octets constant. Par exemple on peut avoir :

   "objet1    objet2    objet3    objet4    objet5    "

On remarque que chaque objet a toujours le mme nombre de lettre (ici : 10 lettres).
L'dition d'un tel script n'est pas trs pratique, c'est pour a que j'ai ajout une
fonction qui permet d'avoir un dump du genre :

   objet1    
   objet2    
   objet3    
   objet4    
   objet5    

Petit conseil pour que a soit plus lisible, changer le " " dans la table par "_" :

   objet1____
   objet2____
   objet3____
   objet4____
   objet5____

Prsent comme a, on peut facilement remarquer les erreurs qu'on aurait pu commettre
sur la longueur d'un mot.

Parlons maintenant de la fonction. La syntaxe est trs simple :
   extraire_fixe(nom_rom, nom_table, nom_texte, adresse_mots, nombre_mots, taille_mot)

Il faut donc donner dans l'ordre :
   - le nom de la rom
   - le nom de la table
   - le nom du fichier texte o sera dump le texte
   - l'adresse du dbut du texte dans la rom
   - le nombre de mots  extraire
   - la taille de chaque mot



 -----------------------------------------------
| 5 - Description de la fonction "inserer_fixe" |
 -----------------------------------------------

La syntaxe est la mme que pour la fonction "extraire_fixe".
Le programme va detecter automatiquement pendant l'insertion des erreurs ventuelles de
taille des mots. Par exemple il completera les mots trop courts (et il signalera la
ligne o se situe l'erreur) et il tronquera les mots trop longs.



 ------------------------------------------------
| 6 - Description de la fonction "optimiser_dte" |
 ------------------------------------------------

Cette fonction a pour but de trouver les meilleurs doublets de lettre dans un fichier
texte. Le syntaxe est la suivante :

   optimiser_dte(nom_texte, nom_out, nombre_dte)

Il faut donc indiquer (dans l'ordre) :
   - le nom du texte  analyser
   - le fichier o seront crites les DTE
   - le nombre de DTE  chercher

Notez bien que les balises ne sont pas prises en compte lors de l'optimisation.



 ------------------------------------------------
| 7 - Description de la fonction "optimiser_mte" |
 ------------------------------------------------

Le fonctionnement de cette fonction est similaire :

   optimiser_mte(nom_texte, nom_out, nombre_mte, taille_max, taille_bibliotheque, [taille_mte])

L'argument "taille_max" correspond  la longueur maximum que pourront avoir les mte.
L'argument "taille_bibliotheque" correspond  la taille que les MTE font utiliser
 l'endroit o elles sont stockes dans la rom.

Les balises ne sont toujours pas prises en compte.
Il est possible de donner la taille d'une mte dans la rom.
Par exemple dans certain jeu, les MTE sont cods sur 2 octets dans le script de la rom,
mais dans d'autres jeux, elles ne sont cods que sur 1 octet, d'o l'interet de ce
dernier argument. Notez bien qu'il est optionnel et que sa valeur par dfaut est 2.



 -------------------------------------------------
| 7 - Description de la fonction "supprimer_mots" |
 -------------------------------------------------

Le fonctionnement de cette fonction est le suivant :

   supprimer_mots(nom_texte, nom_sortie, nom_liste_mots)

Le but de cette fonction est de prendre le fichier texte prcis en premier argument
et d'ignorer chacunes des apparitions de chacun des mots donns dans la liste.

Petit exemple :

On a en entre le texte:
"Il est vraiment super le hareng-tool :D"

Et dans la liste on a :
est
sup
hareng

En sortie on aura :
"Il <est> vraiment <sup>er le <hareng>-tool :D"


Grce  cette fonction on peut combiner une DTE et une MTE facilement dans un programme.
Rappellez vous que les optimisateurs DTE et MTE du programme ignorent tout ce qui se situe
entre < >. Ainsi on peut optimiser une MTE, ignorer les MTE du fichier pour ensuite optimiser
une DTE.


 -------------------------------------------------
| 8 - Description de la fonction "mettre_en_forme" |
 -------------------------------------------------

Le fonctionnement de cette fonction est le suivant :

   mettre_en_forme(nom_texte, nom_sortie, nom_table, largeur_max, hauteur_max)

Cette fonction a pour but  partir d'un fichier (le fichier nom_texte) de crer
un fichier remis en forme de faon  ce que le texte ne dpasse pas du cadre du
jeu une fois insr. Pour ce faire un a besoin d'une table de taille, de la largeur
du cadre et de la hauteur (ou du nombre de lignes) du cadre.

Par exemple, si on a le texte suivant et que le jeu ne peut avoir plus de 15 lettres
par cadre et 2 lignes par cadre :

<PT0001>
Salut je m'appelle S.O.R et voici un exemple de mon module de remise en forme de texte
<FIN>

En sortie on aura :

<PT0001>
Salut je
m'appelle S.O.R
<NEW>
et voici un
exemple de mon
<NEW>
module de
remise en forme
<NEW>
de texte.
<FIN>


Les entres de la table doivent tre de la forme :
a=5
b=6
<Pause>=0

Notez bien qu'une entre peut dpasser une lettre, ce qui peut s'avrer fort utile
quand on a des balises.

Il existe des entres spciales qui permettent de dfinir le retour  la ligne, des balises
d'ouverture de nouveau cadre et des balises de fin de cadre :
\n=LINEBREAK
\n<NEW>\n=NEW_DEFAUT
\n<NEW_AUTO>\n=NEW
\n<FIN>\n\n=FIN

LINEBREAK signifique que la chaine correspondante est un retour  la ligne.
NEW signifie que la chaine est une balise d'ouverture de nouveau cadre, le NEW_DEFAUT
permet de dire au programme quelle balise utiliser dans le cas o il devrait ouvrir un nouveau
cadre.
FIN signifie que la chaine est une balise de fin de texte.

Notez qu'il est obligatoire de donner un LINEBREAK, un NEW_DEFAUT et un FIN.

Enfin, une dernire possibilit est disponible : la balise <Centrer> peut tre ajoute dans le
texte de faon  ce que le texte de la ligne soit centr dans le texte de sortie.
Par exemple :

<PT0001>
<Centrer>Salut !
C'est encore moi
<FIN>

En sortie on aura :
<PT0001>
    Salut !
C'est encore moi
<FIN>

Il faut noter que la balise <Centrer> ne s'applique qu' la ligne o elle se situe. Dans le cas o
la ligne est trop longue et que le programme reviendra  la ligne ou ouvira un nouveau cadre,
il centrera quand mme le texte.


 ------------------------------------------
| 9 - Description de la fonction "patcher" |
 ------------------------------------------

Le fonctionnement de cette fonction est le suivant :

   patcher(nom_rom, nom_patch)

Cette fonction va donc appliquer un patch sur une rom :
   - nom_rom est le nom de la rom  pacher
   - nom_patch est le nom du patch


 -----------------------------------------------
| 10 - Description de la fonction "creer_patch" |
 -----------------------------------------------

Le fonctionnement de cette fonction est le suivant :

   creer_patcher(nom_rom_originale, nom_rom_modifiee, nom_patch)

Cette fonction va donc creer un patch :
   - nom_rom_originale est le nom de la rom originale, celle qui n'a pas t modifie
   - nom_rom_modifiee est le nom de la rom modifie
   - nom_patch est le nom du patch qui va tre cr


 ----------------------------------
| 11 - Informations complmentaires |
 ----------------------------------

Ce programme a t entirement dvelopp par moi-mme, S.O.R ( l'exception de
l'optimisateur MTE : j'ai repris celui qu'Orphis avait fait).
Si vous avez des problmes pour l'utiliser, vous pouvez me mailler  l'adresse
suivante : harengsaur@free.fr . Si vous avez des commentaires ou des
suggestions  faire, merci de me les faire parvenir.
